package org.blogwu.learn.threadLearn.自己实现一个信号量;

import java.util.concurrent.locks.AbstractQueuedSynchronizer;

/**
 * 自己实现一个信号量
 *
 * @author hyf
 * @date 2019-06-26
 **/
public class MySemaphore {


    // 声明同步器
    private Sync sync = null;

    public MySemaphore(int num) {
        sync = new Sync(num);
    }

    // 定义一个同步器，实现AQS类
    private static class Sync extends AbstractQueuedSynchronizer {
        Sync(int num) {
            setState(num);
        }

        @Override
        protected int tryAcquireShared(int arg) {
            for (; ; ) {
                int stat = getState();
                if ((stat - arg) >= 0) {
                    if (compareAndSetState(stat, stat - arg)) {
                        return getState();
                    }
                } else {
                    return -1;
                }
            }
        }

        @Override
        protected boolean tryReleaseShared(int arg) {
            for (; ; ) {
                int stat = getState();
                if (compareAndSetState(stat, stat + arg)) {
                    return true;
                }
            }
        }
    }


    // 获取资源
    public void acquire() {
        sync.acquireShared(1);
    }

    // 释放资源
    public void release() {
        sync.releaseShared(1);
    }
}
